import {weBtoa} from "./weapp-jwt.js"

// ArrayBuffer转16进制字符串示例
function ab2hex(buffer) {
  let hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function(bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}

// 十六进制转十进制
function hex2dex(str) {
  return parseInt(str, 16).toString(10)
}

// 十进制转十六进制
function dex2hex(num) {
  return parseInt(num).toString(16)
}

// 获取数据域部分  substr指定位置，长度
function subData(str,start,length){
  return str.substr(start, length)
}

//字符串（ASCII码）转16进制
function strToHexCharCode(str) {
  if (str === "")
    return "";
  var hexCharCode = [];
  // hexCharCode.push("0x");
  for (var i = 0; i < str.length; i++) {
    // charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数
    hexCharCode.push((str.charCodeAt(i)).toString(16));
  }
  return hexCharCode.join("");
}

//16进制(单个值)转字符（ASCII）
function hexCharCodeToStr(hexCharCodeStr) {
  var trimedStr = hexCharCodeStr.trim();
  var rawStr =
    trimedStr.substr(0, 2).toLowerCase() === "0x" ?
    trimedStr.substr(2) :
    trimedStr;
  var len = rawStr.length;
  if (len % 2 !== 0) {
    alert("Illegal Format ASCII Code!");
    return "";
  }
  var curCharCode;
  var resultStr = [];
  for (var i = 0; i < len; i = i + 2) {
    curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
    // fromCharCode()将 Unicode 编码转为一个字符:
    resultStr.push(String.fromCharCode(curCharCode));
  }
  // console.log('转换后的ASCII：', resultStr);
  return resultStr.join("");
}

//16进制数组转ASCII
const hexArrToCharCode = (hexArr) => {
  var resultStr = [];
  for (var i = 0; i < hexArr.length; i++) {
      let toHex = hexArr[i].toString();
      // fromCharCode()将 Unicode 编码转为一个字符:
      resultStr.push(String.fromCharCode(toHex));
  }
  let toStr = resultStr.join().replace(/,/g, "");
  console.log('转ASCII值后----》', toStr);
  return toStr;
}

/**
 * 前面自动补零
 */
// 方法一
function prefixZero(num) {
  return dex2hex(num).length === 1 ? '0' + dex2hex(num) : dex2hex(num)
}

 //将16进制转ArrayBuffer
 function codebuffer(val) {
  // 将16进制转化为ArrayBuffer
  return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
    // console.log(h);
    // console.log(parseInt(h, 16)); ////十六进制转十进制
    return parseInt(h, 16)
  })).buffer
}

//string to utf8 
// String 转utf8格式的bytes数组，使用encodeURIComponent
function strToUtf8Bytes(text) {
  // encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。 该方法不会对 ASCII 字母和数字进行编码，也不会对这些 ASCII 标点符号进行编码： - _ . ! ~ * ' ( ) 。
  const code = encodeURIComponent(text) //中文字符串转化为UTF-8编码
  // console.log(code);
  const bytes = []
  for (let i = 0;i < code.length;i++) {
    const c = code.charAt(i)
    if (c === '%') {
      // charAt返回字符串指定索引位置的字符
      const hex = code.charAt(i + 1) + code.charAt(i + 2)
      bytes.push(hex)
      // const hexval = parseInt(hex, 16)
      // bytes.push(hexval)
      i += 2
    } else {
      // charCodeAt() charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数
      bytes.push(c.charCodeAt(0).toString(16))
    }
  }
  return bytes
}

// 在前一个函数的基础上，将bytes数组转为ArrayBuffer，用到了DataView对象
function strToArrayBuffer(text) {
  const bytes = strToUtf8Bytes(text)
  const buffer = new ArrayBuffer(bytes.length)
  const dv = new DataView(buffer)
  for (let i = 0;i < bytes.length;i++) {
    // 在相对于视图开始处的指定字节偏移量位置处存储 Uint8 值（0-255）。
    dv.setUint8(i, bytes[i])
  }
  return buffer
}

// utf8格式的Bytes数组转 String
function utf8BytesToStr(bytes) {
  let text = ''
  for (let i = 0;i < bytes.length;i++) {
    text += '%' + bytes[i]
    // text += '%' + bytes[i].toString(16)
  }
  return decodeURIComponent(text)
}


// 中文汉字转Unicode
function ch2unicode(str){
  var value='';
  for (var i = 0; i < str.length; i++) {
    value += '\\u' + left_zero_4(parseInt(str.charCodeAt(i)).toString(16));
  }
  return value;
}

function left_zero_4(str) {
  if (str != null && str != '' && str != 'undefined') {
    if (str.length == 2) {
      return '00' + str;
    }
  }
  return str;
}

 
// unicode转ASCII--作用同strToHexCharCode
function unicode2ascii(str){ 
  var value='';
  for (var i = 0; i < str.length; i++)
    value += '&#' + str.charCodeAt(i) + ';';
  return value;
} 


// Unicode转中文汉字、ASCII转换Unicode
function reconvert(str){ 
  str = str.replace(/(\\u)(\w{1,4})/gi,function($0){ 
    return (String.fromCharCode(parseInt((escape($0).replace(/(%5Cu)(\w{1,4})/g,"$2")),16))); 
  }); 
  str = str.replace(/(&#x)(\w{1,4});/gi,function($0){ 
    return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g,"$2"),16)); 
  }); 
  str = str.replace(/(&#)(\d{1,6});/gi,function($0){ 
    return String.fromCharCode(parseInt(escape($0).replace(/(%26%23)(\d{1,6})(%3B)/g,"$2"))); 
  }); 
  
  return str; 
}
 


//十进制转二进制补码
function dex2bin(n){
  // write code here
  //-123的二进制表示为-1111011，123的为1111011，因此首先要得到负数二进制的补码表示
  //其后面部分的补码0000101 = 122的正码1111011按位取反，
  //这个正码加上前面的0即是再全部按位取反即得-123的补码表示
  if(n < 0) {
    n = -n;
    n = n - 1;
    var str = (Array(8).join("0") + n.toString(2)).slice(-8);
    str = exchange(str);
  }else{
    var str = (Array(8).join("0") + n.toString(2)).slice(-8);
  }
  return str;
}

//如果是负数，0变1，1变0 原码转反码
function exchange(str) {
  var arr = str.split('');
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] == 0) {
      arr[i] = 1;
    } else {
      arr[i] = 0;
    }
  }
  str = arr.join("");
  return str;
}

//二进制转十六进制
function bin_to_hex(str) {
  let hex_array = [{ key: 0, val: "0000" }, { key: 1, val: "0001" }, { key: 2, val: "0010" }, { key: 3, val: "0011" }, { key: 4, val: "0100" }, { key: 5, val: "0101" }, { key: 6, val: "0110" }, { key: 7, val: "0111" },
  { key: 8, val: "1000" }, { key: 9, val: "1001" }, { key: 'a', val: "1010" }, { key: 'b', val: "1011" }, { key: 'c', val: "1100" }, { key: 'd', val: "1101" }, { key: 'e', val: "1110" }, { key: 'f', val: "1111" }]
    let value = ''
    let list = []
    if(str.length% 4 !== 0){
      let a = "0000"
      let b = a.substring(0, 4 - str.length % 4)
      str = b.concat(str)
    }
    while (str.length > 4) {
      list.push(str.substring(0, 4))
      str = str.substring(4);
    }
    list.push(str)
    for (let i = 0; i < list.length; i++) {
      for (let j = 0; j < hex_array.length; j++) {
        if (list[i] == hex_array[j].val) {
          value = value.concat(hex_array[j].key)
          break
        }
      }
    }
    return value
}

// 判断字符串中是否包含中文
function includeChinese(s) {
  var patrn = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi;
  if(!patrn.exec(s)) {
    return false;
  } else {
    return true;
  }
}

// 计算和校验
function computeCRC(str){
  let expCRC = []
  for (let index = 0; index < str.length; index++) {
    // 两个字符表示一个byte
    if (str.substr(index * 2, 2)) {
      expCRC.push(str.substr(index * 2, 2))
    }else{
      break;
    }
  }
  // console.log(expCRC);
  const expCRCSum = expCRC.map(item => {
    return '0x' + item
  }).reduce((sum, cur) => {
    return sum + parseInt(cur)
  }, 0)
  const CRC = 0 - expCRCSum
  // console.log(CRC);
  // 二进制补码转为16进制
  // console.log(bin_to_hex(dex2bin(CRC)));
  return bin_to_hex(dex2bin(CRC))
}

// 整包数据（数组形式）
// function integrateDataPackage(str, fieldType = '01'){
//   let partData = []
//   if (str.length > 14) {
//     for (let index = 0; index < str.length; index++) {
//       let strCode = str.substr(index * 14, 14) //超过14byte的截取出来放到partData中
//       if (strCode.length) {
//         partData.push(strCode)
//       }else{
//         break;
//       }
//     }
//   }else{
//     partData.push(str)
//   }
//   const packageSign = partData.length === 1 ? '00' : prefixZero(partData.length)
//   // console.log(partData);
//   const finallData = partData.map((item, index) => { 
//     const packageNum = prefixZero(index + 1)
//     const lenHex = prefixZero(item.length)
//     const dataDomain = strToHexCharCode(item)
//     return ('A0' + fieldType + packageSign + packageNum + lenHex + dataDomain)
//   }).map(expCRC => {
//     // console.log(computeCRC(expCRC));
//     return expCRC + computeCRC(expCRC)
//   })
//   return finallData
// }
function integrateDataPackage(str, fieldType = '01'){
  let partData = []
  const dataDomain = strToUtf8Bytes(str).join('')
  // const dataDomain = strToHexCharCode(str)
  // console.log(dataDomain);
  if (dataDomain.length > 28) {
    for (let index = 0; index < dataDomain.length; index++) {
      let strCode = dataDomain.substr(index * 28, 28) //超过14byte的截取出来放到partData中
      if (strCode.length) {
        partData.push(strCode)
      }else{
        break;
      }
    }
  }else{
    partData.push(dataDomain)
  }
  const packageSign = partData.length === 1 ? '00' : prefixZero(partData.length)
  // console.log(partData);
  const finallData = partData.map((item, index) => { 
    const packageNum = prefixZero(index + 1)
    const lenHex = prefixZero(item.length / 2)
    return ('A0' + fieldType + packageSign + packageNum + lenHex + item)
  }).map(expCRC => {
    // console.log(computeCRC(expCRC));
    const integrateData = expCRC + computeCRC(expCRC)
    return integrateData.toLowerCase()  //全部转为小写
    // return integrateData.toUpperCase()  //全部转为大写
  })
  return finallData
}

// 十六进制转二进制
function hex_to_bin(str) {
  let hex_array = [{key:0,val:"0000"},{key:1,val:"0001"},{key:2,val:"0010"},{key:3,val:"0011"},{key:4,val:"0100"},{key:5,val:"0101"},{key:6,val:"0110"},{key:7,val:"0111"},
      {key:8,val:"1000"},{key:9,val:"1001"},{key:'a',val:"1010"},{key:'b',val:"1011"},{key:'c',val:"1100"},{key:'d',val:"1101"},{key:'e',val:"1110"},{key:'f',val:"1111"}]

  let value=""
  for(let i=0;i<str.length;i++){
      for(let j=0;j<hex_array.length;j++){
          if(str.charAt(i).toLowerCase()== hex_array[j].key){
              value = value.concat(hex_array[j].val)
              break
          }
      }
  }
  console.log(value)
  return value
}

// 十六进制转为base64
function hexToBase64(hexstring) {
  return weBtoa(hexstring.match(/\w{2}/g).map(function(a) {
      return String.fromCharCode(parseInt(a, 16));
  }).join(""));
}

/**
 * base64转为本地地址
 * @param {*} base64data 
 * @param {*} fun 回调函数
 */
const base64src = (base64data, fun) => {
  const base64 = base64data; //base64格式图片
  const time = new Date().getTime();
  const imgPath = wx.env.USER_DATA_PATH + "/instrument" + time + ".jpg";
  //如果图片字符串不含要清空的前缀,可以不执行下行代码.
  const imageData = base64.replace(/^data:image\/\w+;base64,/, "");
  const file = wx.getFileSystemManager();
  file.writeFileSync(imgPath, imageData, "base64");
  fun(imgPath);
};


module.exports = {
  ab2hex: ab2hex,
  hex2dex: hex2dex,
  dex2hex: dex2hex,
  subData: subData,
  strToHexCharCode: strToHexCharCode,
  hexCharCodeToStr: hexCharCodeToStr,
  hexArrToCharCode: hexArrToCharCode,
  prefixZero: prefixZero,
  codebuffer: codebuffer,
  strToUtf8Bytes: strToUtf8Bytes,
  strToArrayBuffer: strToArrayBuffer,
  utf8BytesToStr: utf8BytesToStr,
  ch2unicode: ch2unicode,
  unicode2ascii: unicode2ascii,
  reconvert: reconvert,
  includeChinese: includeChinese,
  computeCRC: computeCRC,
  integrateDataPackage: integrateDataPackage,
  hex_to_bin: hex_to_bin,
  hexToBase64: hexToBase64,
  base64src: base64src
}